#include "adc_dev.h"

static struct rt_device adc;
#define ADC_GET_NUM     (10)

static rt_err_t adc_init(rt_device_t dev)  
{  
  ADC_InitTypeDef  ADC_InitStructure;  
  GPIO_InitTypeDef GPIO_InitStructure;  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  GPIO_InitStructure.GPIO_Pin  =GPIO_Pin_1;  
  GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AIN;  
  GPIO_Init(GPIOA,&GPIO_InitStructure);  

  ADC_InitStructure.ADC_Mode              = ADC_Mode_Independent;  //独立模式  
  ADC_InitStructure.ADC_ScanConvMode      =DISABLE;      //连续多通道模式  
  ADC_InitStructure.ADC_ContinuousConvMode =ENABLE;      //连续转换  
  ADC_InitStructure.ADC_ExternalTrigConv  = ADC_ExternalTrigConv_None; //转换不受外界决定  
  ADC_InitStructure.ADC_DataAlign         =ADC_DataAlign_Right;   //右对齐  
  ADC_InitStructure.ADC_NbrOfChannel      =1;       //扫描通道数  
  ADC_Init(ADC1,&ADC_InitStructure);  
  ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 1,ADC_SampleTime_239Cycles5);  
  ADC_Cmd  (ADC1,ENABLE);             //使能或者失能指定的ADC  
  ADC_ResetCalibration(ADC1);  
  while(ADC_GetResetCalibrationStatus(ADC1));  
  ADC_StartCalibration(ADC1);  
	while(ADC_GetCalibrationStatus(ADC1));
  rt_kprintf("ACD init Finsh\n\r");  

	return RT_EOK;
}  

static rt_err_t adc_open(rt_device_t dev, rt_uint16_t oflag)
{
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能或者失能指定的ADC的软件转换启动功能		
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET); //检查制定ADC标志位置1与否 ADC_FLAG_EOC 转换结束标志位  
	return RT_EOK;
}

static rt_err_t adc_close(rt_device_t dev)
{
	ADC_SoftwareStartConvCmd(ADC1,DISABLE);
	ADC_Cmd  (ADC1,DISABLE);  
	return RT_EOK;
}


static rt_size_t adc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
	rt_uint32_t value;
	rt_uint16_t run = ADC_GET_NUM;

	value = ADC_GetConversionValue(ADC1);
	value = 0;
	do 
	{
		while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
		value += ADC_GetConversionValue(ADC1);
		//rt_kprintf("run=%d  adc=%d cur=%d\n",run,value,ADC_GetConversionValue(ADC1));
	}while(--run);
	value /= ADC_GET_NUM;
	rt_memcpy(buffer, &value, sizeof(rt_uint32_t));
	return 4;
}

int rt_hw_adc_init(void)
{
	adc.type = RT_Device_Class_Char;
	adc.init = adc_init;
	adc.open = adc_open;
	adc.close = adc_close;
	adc.read = adc_read;
	adc.write = RT_NULL;
	adc.control = RT_NULL;
	rt_device_register(&adc, DEVICE_NAME_VBAT, RT_DEVICE_FLAG_RDONLY);
	rt_kprintf("ACD init.....OK\n\r");  
	return 0;
}

INIT_DEVICE_EXPORT(rt_hw_adc_init);




#ifdef RT_USING_FINSH  
#include <finsh.h>  
void adc(void)  
{  
  rt_int32_t adc;  
  float vbat;

  rt_kprintf("hello here is a ADC test\n\r");  
  ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能或者失能指定的ADC的软件转换启动功能  
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET); //检查制定ADC标志位置1与否 ADC_FLAG_EOC 转换结束标志位  
  adc = ADC_GetConversionValue(ADC1);  
  rt_kprintf("ADC: %dV\n\r", adc);  
  vbat = adc;
  vbat /= 4095.0;
  adc = vbat*10000;
  rt_kprintf("ADC: vbat %d\n", adc);  
  rt_thread_delay( RT_TICK_PER_SECOND/2 );  
}  
FINSH_FUNCTION_EXPORT(adc, start adc function test.)  


void gpio_test(int pin,int value)
{
  rt_pin_mode(pin,PIN_MODE_OUTPUT); //开机脚
  rt_pin_write(pin, value);

  rt_kprintf("set gpio %d value=%d\n",pin,value);
}
//FINSH_FUNCTION_EXPORT(gpio_test,gpio test);

extern rt_uint8_t elsPicBuf1[2][3*1024];
void compress_test(void)
{
	int i,j;
	qlz_state_compress *state;
	qlz_state_decompress *state1;
	rt_size_t size = 2*1024;

	state = rt_calloc(1, sizeof(qlz_state_compress));
	RT_ASSERT(state);
	list_mem();
	for(i=0;i<3;i++)
	{
		for(j=0;j<1024;j++)
		{
			elsPicBuf1[1][i*1024+j] = j;
		}
	}
	show_int_string(elsPicBuf1[1], size);
	size = qlz_compress(elsPicBuf1[1],elsPicBuf1[0],size,state);
	rt_free(state);
	rt_kprintf("compress size = %d\n",size);
	show_hex_string(elsPicBuf1[0],size);
	for(i=0;i<3;i++)
	{
		for(j=0;j<1024;j++)
		{
			elsPicBuf1[1][i*1024+j] = 0;
		}
	}
	state1 = rt_calloc(1, sizeof(qlz_state_decompress));
	RT_ASSERT(state);
	size = qlz_decompress(elsPicBuf1[0], elsPicBuf1[1], state1);
	rt_kprintf("decompress size = %d\n",size);
	show_int_string(elsPicBuf1[1], size);
	rt_free(state1);
	list_mem();
}

void pic_data_dacompress(rt_uint8_t *zip,rt_uint8_t *data)
{
	qlz_state_decompress *state;

	state = rt_calloc(1, sizeof(qlz_state_decompress));
	RT_ASSERT(state);

	qlz_decompress(zip,data,state);
	
	rt_free(state);
}



#endif  



